
//***************************************************************************
//                       ColGeometry
//***************************************************************************

#ifndef ColGeometry_H
#define ColGeometry_H
#if defined(__sgi) || defined(_WIN32)
#pragma once
#endif

//---------------------------------------------------------------------------
//  Includes
//---------------------------------------------------------------------------

#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
#include <assert.h>

#include <config.h>
#include <col_import_export.h>
#include <ColDefs.h>
#include <ColMath.h>

namespace col {

//---------------------------------------------------------------------------
//   Constants
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
//   Types
//---------------------------------------------------------------------------

/** type of the primitives in this geometry
 */
typedef enum
{
	ANY,
	TRIANGLES,
	QUADS
} PrimitiveTypeE;

/** type of the normals in this geometry
 */
typedef enum
{
	PER_VERTEX,
	PER_PRIMITIVE
} NormalTypeE;
		
	
/** store the indices of the points in each primitive
 */
typedef std::vector<unsigned int> Primitive;

/** the type of arrays, which store the data of geometry
 */
typedef std::vector<Point3f>   Pnt3Array;
typedef std::vector<Vector3f>  Vec3Array;
typedef std::vector<Primitive> PrimArray;


//***************************************************************************
//  ColGeometry 
//***************************************************************************

/** @class ColGeometry
 *
 *  @brief keep the geometry data of the collision object
 *
 */
class COL_EXPORTIMPORT ColGeometry
{
public:
	ColGeometry();
	ColGeometry( const Pnt3Array &points, const PrimArray &prims, PrimitiveTypeE pt = ANY );
	ColGeometry( const ColGeometry & source );
	
	const ColGeometry& operator=( const ColGeometry & source );

	Pnt3Array* editPointsPtr();
	PrimArray* editPrimitivesPtr();

	const Pnt3Array* getPointsPtr() const;
	const PrimArray* getPrimitivesPtr() const;

	const Pnt3Array& getPoints() const;
	const PrimArray& getPrimitives() const;

	const PrimitiveTypeE getPrimType() const;
	void setPrimType ( const PrimitiveTypeE pt );

	const NormalTypeE getNormalType( void ) const;
	void setNormalType( const NormalTypeE nt );

	void getBBox( float  min[], float  max[] ) const;
	void getBBox( double min[], double max[] ) const;
	void getBBox( Point3  &min, Point3  &max ) const;

	void clearOldData( void );
	void updateBBox( void );
	
	void print( FILE * fp = stdout ) const;
	int printToObj( const char *file_name ) const;

	void importDataFromArray( const unsigned int prim_length,
							  const REAL *points, 
							  const unsigned int np,
							  const unsigned int *indices,
							  const unsigned int ni );

	void importDataFromArray( const unsigned int prim_length,
							  const REAL *points, 
							  const unsigned int np,
							  const unsigned int * indices,
							  const unsigned int ni,
							  const REAL *normals,
							  const NormalTypeE nt );

private:
	/** the name of this geometry, which is a pointer to native c-type string
	 */
	const char * m_name;

	/// all the points of this geometry
	Pnt3Array m_points;
	
	/** all the normals of this geometry, which could be per-vertex or
	 *  per-primitive
	 */
	Vec3Array m_normals;
	/// the type of the normals in this geometry
	NormalTypeE m_nt;
	
	/// all the primitives of this geometry
	PrimArray m_primitives;
	/// the type of the primitives in this geometry
	PrimitiveTypeE m_pt;

	/// the min corner point of BBox
	float m_bboxmin[3];
	/// the max corner point of BBox,
	float m_bboxmax[3];
};

} // namespace col

#endif // ColGoemetry_H
